#! python3
# -*- coding: utf-8 -
'''
Created on 2017年05月10日
@author: zxyong 13738196011
'''

import sqlite3
import mysql.connector
import threading
import time
from com.zxy.common import Com_Para
from com.zxy.common.Com_Fun import Com_Fun
from com.zxy.db2.PooledConnection2 import PooledConnection2
from com.zxy.z_debug import z_debug
class ConnectionPool2(z_debug):
    attJdbcDriver = ""
    attDbUrl = ""
    attDbUsername = ""
    attDbPassword = ""
    attInitialConnections = 5
    attIncrementalConnections = Com_Para.incrementalConnections
    attMaxConnections = Com_Para.maxConnections
    attPooledConnection2s = []
    def __init__(self, inputJdbcDriver, inputDbUrl, inputDbUsername, inputDbPassword): 
        self.attJdbcDriver = inputJdbcDriver
        if inputJdbcDriver == "org.sqlite.JDBC":
            self.attInitialConnections = 2
            self.attMaxConnections = 10
        self.attDbUrl = inputDbUrl
        self.attDbUsername = inputDbUsername
        self.attDbPassword = inputDbPassword
        try:
            self.createPool()
        except Exception as e:
            if str(type(self)) == "<class 'type'>":
                self.debug_in(self,repr(e))#打印异常信息
            else:
                self.debug_in(repr(e))#打印异常信息
        finally:
            pass
    def createPool(self):
        if len(self.attPooledConnection2s) == 0:
            lock = threading.Lock()
            if lock.acquire():
                self.createConnections(self.attInitialConnections) 
                if str(type(self)) == "<class 'type'>":
                    self.debug_in(self,"the 2 create pool")#打印异常信息
                else:
                    self.debug_in("the 2 create pool")#打印异常信息  
                lock.release()
    def createConnections(self, inputNumConnections):
        if self.attMaxConnections > 0 and len(self.attPooledConnection2s) >= self.attMaxConnections:
            if str(type(self)) == "<class 'type'>":
                self.debug_in(self,"the 2 连接数己经达到最大")#打印异常信息
            else:
                self.debug_in("the 2 连接数己经达到最大")#打印异常信息
            self.findFreeConnection()
        for iIndex in range(0,inputNumConnections):
            try:
                temCon = self.newConnection()
                temPolCon = PooledConnection2(temCon)
                self.attPooledConnection2s.append(temPolCon)          
            except Exception as e:
                if str(type(self)) == "<class 'type'>":
                    self.debug_in(self,repr(e))#打印异常信息
                else:
                    self.debug_in(repr(e))#打印异常信息
    def newConnection(self):        
        if self.attJdbcDriver == "org.sqlite.JDBC":
            temConn = sqlite3.connect(self.attDbUrl,check_same_thread = False)
            return temConn
        elif self.attJdbcDriver == "com.mysql.jdbc.Driver":
            try:
                temConn = mysql.connector.Connect(host=self.attDbUrl.split(":")[0],user=self.attDbUsername,db=self.attDbUrl.split(":")[2],passwd=self.attDbPassword,port=self.attDbUrl.split(":")[1])
                return temConn
            except Exception as e:
                if str(type(self)) == "<class 'type'>":
                    self.debug_in(self,repr(e))#打印异常信息
                else:
                    self.debug_in(repr(e))#打印异常信息
        else:
            return None
    def getConnection(self):
        temReturnResult = None
        lock = threading.Lock()
        if lock.acquire():
            if len(self.attPooledConnection2s) == 0:
                return None
            else:
                temReturnResult = self.getFreeConnection()    
                while self.attPooledConnection2s is None:
                    time.sleep(0.2)
                    temReturnResult = self.getFreeConnection()
            lock.release()
        return temReturnResult
    def getFreeConnection(self):
        temConn_self = self.findFreeConnection()
        if temConn_self is None:
            self.createConnections(self.attIncrementalConnections)
            temConn_self = self.findFreeConnection()
            if temConn_self is None:
                return None
        return temConn_self
    def findFreeConnection(self):
        temPc = None
        while temPc is None:
            for i in range(len(self.attPooledConnection2s)):
                temPc = self.attPooledConnection2s[i]
                if temPc.attBusy == False or temPc.attConnection is None:
                    temPc.attBusy = True
                    try:
                        if temPc.attConnection is None :
                            temPc.attConnection = self.newConnection()                        
                    except Exception as e:
                        del self.attPooledConnection2s[i]
                        i = i - 1
                        if str(type(self)) == "<class 'type'>":
                            self.debug_in(self,repr(e))#打印异常信息
                        else:
                            self.debug_in(repr(e))#打印异常信息
                        continue
                    break
                if temPc.attConnection is not None:
                    break
                else:
                    time.sleep(0.5)
        return temPc
    def closeConnection(self,inputConn):
        try:
            inputConn.close()
            if str(type(self)) == "<class 'type'>":
                self.debug_in(self,"the 2关闭并当前总连接数:"+str(len(self.attPooledConnection2s)))#打印异常信息
            else:
                self.debug_in("the 2关闭并当前总连接数:"+str(len(self.attPooledConnection2s)))#打印异常信息
        except Exception as e:
            if str(type(self)) == "<class 'type'>":
                self.debug_in(self,repr(e))#打印异常信息
            else:
                self.debug_in(repr(e))#打印异常信息
    def closeConnectionPoolTimeOut(self):
        pass
    def returnConnection(self,inputConn):
        if len(self.attPooledConnection2s) == 0:
            if str(type(self)) == "<class 'type'>":
                self.debug_in(self,"the 2 db  连接池不存在，无法返回此连接到连接池中!")#打印异常信息
            else:
                self.debug_in("the 2 db  连接池不存在，无法返回此连接到连接池中!")#打印异常信息
            return None
        for i in range(len(self.attPooledConnection2s)):
            temPConn = self.attPooledConnection2s[i]            
            if temPConn.attConnection == inputConn and temPConn.attBusy:
                temPConn.attBusy = False
                break